<?php


namespace Aoe\Emulator\Ui;

use Aoe\Emulator\Ifc\Key;
use Aoe\Emulator\Ifc\Vu;
use Aoe\Emulator\Ui\Widget\Widget;
use Exception;
use JetBrains\PhpStorm\ArrayShape;
use Throwable;


/**
 * ## Form
 *
 *    'row': URL 数据地址
 *    'label-position': 'left', 'right', 'top', 'none'
 *    'label-width': {int}px
 *    'size': medium/small/large 尺寸
 *    'fields': Field[]
 *    'toolbar': Toolbar
 *
 */
class Form extends Component
{
    const string LABEL_WIDTH    = 'label-width';
    const string LABEL_POSITION = 'label-position';
    const string ROW            = 'row';
    const string TOP            = 'top';
    const string SIZE           = 'size';
    const string PAYLOAD        = 'payload';
    const string REDIRECT       = 'redirect';
    const string JSON           = 'json';
    const string DIFF           = 'diff';

    private static array $copied = [
        self::SIZE,
        Key::LABEL,
        self::JSON,
        self::DIFF,
        Vu::STYLE,
        Key::NAME,
        self::REDIRECT,
    ];

    private static array $actions = [
        Key::VIEW_ADD => Key::API_INSERT,
        Key::VIEW_EDIT => Key::API_UPDATE,
    ];
    
    /**
     * @throws Exception
     */
    #[ArrayShape([
        Vu::TOOLBAR          => "array",
        self::LABEL_WIDTH    => "string|int",
        self::LABEL_POSITION => "string",
        Key::ELEMENTS        => "array",
        self::ROW            => "string",
        self::SIZE           => "string",
    ])]
    public function render(?array $declarer = null): array
    {
        if (null === $declarer) $declarer = $this->declarer;
        
        $form = $this->copy(self::$copied, $declarer);
        
        $form[Key::LABEL] = $declarer[Key::LABEL] ?? $declarer[Key::NAME];
        $form[self::LABEL_POSITION] = $declarer[self::LABEL_POSITION] ?? self::TOP;
        if ($form[self::LABEL_POSITION] !== self::TOP)
            $form[self::LABEL_WIDTH] = $declarer[self::LABEL_WIDTH] ?? 100;
        
        $form[Key::ELEMENTS] = Widget::renderWidgets($this->context, $declarer[Key::ELEMENTS]);
        
        if (isset($declarer[Vu::TOOLBAR]))
            $form[Vu::TOOLBAR] = new Toolbar($this->context)->renderButtons($declarer[Vu::TOOLBAR]);

        try {
            $form[self::SUBMIT] =
                $declarer[self::SUBMIT] ?? $this->pathinfo($this->_get_api($this->context->action));
        }catch (Throwable){}

        if (isset($declarer[Component::API])) {
            $form[Component::API] = $declarer[Component::API];
        } elseif (isset($declarer[self::PAYLOAD])) {
            $form[Component::API] = $this->pathinfo('row') . '?id';
        }
        
        //$params = $this->request->getParam();
        //if ($params) $form['modelValue'] = $params;
        
        return $form;
    }
    
    private function _get_api(string $view): string
    {
        return self::$actions[$view] ?? Key::API_INSERT;
    }
}